//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include "gevent.h"
#include <aura.h>

CGhostEvent::~CGhostEvent()
{
    if (NULL != m_hEvent) {
        AuraEvent_Destroy(m_hEvent);
        m_hEvent = NULL;
    }
}

ECode CGhostEvent::Initialize(
    /* [in]  */ Boolean bManualReset,
    /* [in]  */ EventState initialState)
{
    return (ECode)AuraEvent_Create((Aura_Bool)bManualReset, (Aura_EventState)initialState, &m_hEvent);
}

UInt32 CGhostEvent::AddRef(void)
{
    Int32 nRefs = m_nRefs.Increment();

    return (UInt32)nRefs;
}

UInt32 CGhostEvent::Release(void)
{
    Int32 nRefs = m_nRefs.Decrement();

    if (0 == nRefs) {
        GhostFactory factory(this->GetOid());
        Ghost::S_DeleteGhost(&factory, this);
        delete this;
    }

    return (UInt32)nRefs;
}

ECode CGhostEvent::TryWait(
        /* [in]  */ Millisecond32 msTimeOut,
        /* [in]  */ WaitResult * pResult,
        /* [in]  */ EventState * pState)
{
    assert(NULL != pResult);
    assert(NULL != pState);

    return (ECode)AuraEvent_Wait(m_hEvent, (Aura_Millisecond32)msTimeOut, (Aura_WaitResult *)pResult, (Aura_EventState *)pState);
}

ECode CGhostEvent::Notify(
        /* [in]  */ EventState state)
{
    assert(UNSIGNALED != state);
    return (ECode)AuraEvent_Signal(m_hEvent, (Aura_EventState)state);
}

ECode CGhostEvent::Clear()
{
    return (ECode)AuraEvent_Unsignal(m_hEvent);
}

ECode CGhostEventFactory::CreateGhost(
        /* [out] */ Ghost ** ppGhost,
        /* [out] */ Boolean * pExisted)
{
    CGhostEvent * pGhost = NULL;
    ECode ec = NOERROR;

    assert(NULL != ppGhost);
    assert(NULL == pExisted);

    pGhost = new CGhostEvent();
    if (NULL == pGhost) {
        ec = E_OUT_OF_MEMORY;
        goto ErrorExit;
    }
    ec = pGhost->Initialize(m_bManualReset, m_initialState);
    if (FAILED(ec)) {
        goto ErrorExit;
    }
    pGhost->AddRef();
    *ppGhost = pGhost;

    return ec;

ErrorExit:
    if (NULL != pGhost) {
        delete pGhost;
    }
    return ec;
}

